/*
 * ******************************************************************************
 * Class: Singleton	
 * 
 * @author: Teresa Mafalda dos Reis Frazao
 * @version:April 10, 2014 
 * 
 * This class manages the objects which can only have a code instance.
 * These objects are the service registers handled by DependencyListUtils.
 * ******************************************************************************
 */
package com.feedzai.service.utils;


/**
 * The Class Singleton.
 */
public final class Singleton {

	/** The Singleton instance. */
	private static Singleton instance;
	
	
	/** The global register for service node ids. 
	 * Thus, since ID are unique, the singleton ensures no duplicated IDs 
	 * */
	private static Long serviceNodeId;
	
	
	/** 
	 * The dependency list utils. 
	 * We include this element in the singleton, since we want only one instance of each data structure
	 * */
	private static Register dependencyListUtils;
	
	
	/**
	 * Instantiates only a singleton instance.
	 */
	private Singleton() 
	{

		// Initialize the node id assigned to each service
		serviceNodeId = (long) 0;
		
		// Initialize the data structures utils
		dependencyListUtils = new Register();
	}
	
	
	/*
	 * ---------------------------------------------------------------------------
	 * 							Public Interface 
	 * ---------------------------------------------------------------------------
	 */
	

	/**
	 * Gets the single instance of Singleton.
	 * <code>synchronized</code> is used to avoid race conditions between service threads.
	 *
	 * @return single instance of Singleton
	 */
	public static Singleton getInstance() 
	{
		// 
		// Please note this leads to a code violation but we need to check 
		// again since there are multiple threads.		
		//
		if (instance == null) 
		{
			synchronized (Singleton.class) 
			{
				if (instance == null) 
				{
					instance = new Singleton();
				}
			}
		}
		return instance;
	}	
	
	
	/**
	 * Gets a new service id.
	 *
	 * @return the new id
	 */
	public Long getNewId() 
	{
		// 
		// First we check if there is a valid ID
		// If not, we create a new one.
		//
		if(serviceNodeId == null)
		{
			synchronized (serviceNodeId) {
				// Value is ONE since we will not increment the value
				serviceNodeId = (long) 1;
			}
		}
	
		//
		// If there is an id we can return
		else
		{
			synchronized (serviceNodeId) {

				serviceNodeId += 1;
			}
		}
	
		return serviceNodeId;
	}


	/**
	 * Gets the dependency list utils.
	 *
	 * @return the dependency list utils
	 */
	public static synchronized Register getDependencyListUtils() 
	{
		return dependencyListUtils;
	}


	/**
	 * Sets the dependency list utils.
	 *
	 * @param dependencyListUtils the new dependency list utils
	 */
	public static synchronized void setDependencyListUtils(Register dependencyListUtils) 
	{
		Singleton.dependencyListUtils = dependencyListUtils;
	}
	
}
